package com.jillchen.grpc.server.services;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jillchen.grpc.libs.DocsFileConvertGrpc;
import com.jillchen.grpc.libs.ConvertFile;
import com.jillchen.grpc.server.convertprovidors.ConvertPdf;
import com.jillchen.grpc.server.entitys.ExtType;
import com.jillchen.grpc.server.utils.AbsConverter;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import net.devh.springboot.autoconfigure.grpc.server.GrpcService;
import org.apache.commons.io.FilenameUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@GrpcService(ConvertFile.class)
public class ConvertFileAndWatermark extends DocsFileConvertGrpc.DocsFileConvertImplBase {
    @Override
    public void convert(ConvertFile.RequestConvertFile request, StreamObserver<ConvertFile.ResponseFileConvertReply> responseObserver)  {
        String InputFileStr = request.getInputFilePath();
        String OutputFileStr = request.getOutputFilePath();
        String InExt = FilenameUtils.getExtension(InputFileStr).toLowerCase();
        String OutExt = FilenameUtils.getExtension(OutputFileStr).toLowerCase();


        String WaterMarkFilePath = request.getWaterMarkFilePath();
        String WaterMarkText = request.getWaterMarkText();
        String WaterMarkedPath = request.getWaterMarkedPath();


        //读取配置文件
        Resource resource = new ClassPathResource("conf/FileMap.json");
        InputStream is = null;
        try {
            is = resource.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
        int ch = 0;
        StringBuffer sb = new StringBuffer();
        while (true) {
            try {
                if (!((ch = reader.read()) != -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            sb.append((char) ch);
        }
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String jsonStr = sb.toString();
        HashMap<String, HashMap<ExtType, List<String>>> map = new Gson().fromJson(jsonStr, new TypeToken<HashMap<String, HashMap<ExtType, List<String>>>>() {
        }.getType());


        String ConvertClass = "Pdf";
        for (Map.Entry<String, HashMap<ExtType, List<String>>> entry : map.entrySet()) {

            HashMap<ExtType, List<String>> sub_map = entry.getValue();

            boolean infind_int = false;

            boolean outfind_int = false;
            List<String> InList = sub_map.get(ExtType.INPUTExt);
            List<String> OunList = sub_map.get(ExtType.OUTPUTExt);

            for (String Item : InList) {
                if (Item.toUpperCase().equals(InExt.toUpperCase())) {
                    infind_int = true;
                    break;
                }
            }
            for (String Item : OunList) {
                if (Item.toUpperCase().equals(OutExt.toUpperCase())) {
                    outfind_int = true;
                    break;
                }
            }
            if (infind_int && outfind_int) {
                ConvertClass = entry.getKey();
                break;
            }
        }
        Class<?> cls = null;
        try {
            System.out.println("Use Convert Provider:"+ConvertClass);
            cls = Class.forName("com.jillchen.grpc.server.convertprovidors.Convert" + ConvertClass);
        } catch (ClassNotFoundException e) {

            final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
            replyBuilder.setMessages(String.format("不支持类型%s to %s", InExt, OutExt));
            replyBuilder.setStatus(-1);
            responseObserver.onNext(replyBuilder.build());
            responseObserver.onCompleted();
            return;
        }
        AbsConverter convert = new ConvertPdf();
        try {

            convert = (AbsConverter) cls.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        int result = -1;
        if (!OutputFileStr.equals("")) {
            result = convert.Convert(InputFileStr, OutputFileStr);
        } else {
            final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
            replyBuilder.setMessages("保存路径错误");
            replyBuilder.setStatus(-1);
            responseObserver.onNext(replyBuilder.build());
            responseObserver.onCompleted();
            return;
        }
        if (result != 0) {
            final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
            replyBuilder.setMessages(String.format("转换失败%s to %s", InExt, OutExt));
            replyBuilder.setStatus(-1);
            responseObserver.onNext(replyBuilder.build());
            responseObserver.onCompleted();
            return;
        }
        if("".equals(WaterMarkFilePath)&&"".equals(WaterMarkText)&&"".equals(WaterMarkedPath))
        {
            final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
            replyBuilder.setMessages(String.format("%s to %s convert ok", InExt, OutExt));
            replyBuilder.setStatus(1);
            responseObserver.onNext(replyBuilder.build());
            responseObserver.onCompleted();
            return;
        }

        result=-1;
        try {
            result=  convert.WaterMark(OutputFileStr,WaterMarkFilePath,WaterMarkText,WaterMarkedPath);
        } catch (Exception e) {
            result=-1;
        }

        if(result!=0)
        {
            final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
            replyBuilder.setMessages(String.format("转换失败%s to %s", InExt, OutExt));
            replyBuilder.setStatus(-1);
            responseObserver.onNext(replyBuilder.build());
            responseObserver.onCompleted();
            return;
        }

        final ConvertFile.ResponseFileConvertReply.Builder replyBuilder = ConvertFile.ResponseFileConvertReply.newBuilder();
        replyBuilder.setMessages(String.format("%s to %s convert ok", InExt, OutExt));
        replyBuilder.setStatus(1);
        responseObserver.onNext(replyBuilder.build());
        responseObserver.onCompleted();
        return;

    }
}
